" Author:	Zhang Kang <progliker@gmail.com>
" Last Update:	2010-06-04
" Thanks:	Godson@ustcbbs 
"               http://home.ustc.edu.cn/~stephen1/script/vimrc.html

" 关闭兼容模式
set nocompatible

let mapleader = ";"

" 使用空格进入shell
nmap <space> :shell<CR>

" 检查操作系统
if has("win32") || has("win64") || has("win32unix")
    let g:isWin = 1
else
    let g:isWin = 0
endif

" 检查GUI
if has("gui_running")
    let g:isGUI = 1
else
    let g:isGUI = 0
endif

" 关掉Toolbar
if (g:isGUI) 
    set guioptions-=T
endif

" 快速编辑vimrc
if (g:isWin) 
    map <silent> <leader>ee :e $HOME\_vimrc<CR>
    autocmd! bufwritepost *.vimrc source $HOME\_vimrc
else
    map <silent> <leader>ee :e $HOME/.vimrc<CR>
    autocmd! bufwritepost *.vimrc source $HOME/.vimrc
endif

" 快速保存文件
nmap <leader>ww :w!<CR>

" 快速关闭文件
nmap <leader>qq :x<CR>

syntax   enable		" syntax highlight
filetype plugin on	" enable filetype detection
filetype indent on	" enable filetype indent 

set backspace=indent,eol,start
" set whichwrap+=<,>,h,l	" 退格键和方向键可以换行
set number		" 显示行号
set showcmd		" 显示命令
set incsearch		" 增量式搜索
set hlsearch		" 高亮搜索
set magic		" 扩展正则表达式
set autoindent		" 自动缩进
set smartindent		" 智能缩进
set cindent		" C/C++风格缩进
set nobackup		" 关闭备份
set nowritebackup	" 关闭写前备份
set linebreak		" 在breakat字符处断行
set wildmenu

" tab为四个空格
set shiftwidth=4
set shiftround
set tabstop=8
set smarttab
set expandtab

set history=400
set autoread
set mouse=a
set background=dark
colorscheme default

" 设置状态栏
set laststatus=2        " 总是显示状态栏
highlight StatusLine cterm=bold ctermfg=yellow ctermbg=blue
set statusline=[%n]\ %f%m%r%h%w\ [TYPE=%Y]\ [ASCII=\%03.3b]\ [HEX=\%02.2B]\ [POS=%l,%v,%c]\ [%p%%]\ [LEN=%L]

if (g:isGUI)
    colorscheme torte
    set cursorline
    hi Cursorline guibg=#222222
    if (!g:isWin)
        set guifont=Monospace\ 15
        set guifontwide=Monospace\ 15
    endif
endif

if (g:isWin)
    let &termencoding=&encoding
    set fileencodings=utf8,cp936,ucs-bom,latin1
else
    set encoding=utf8
    set fileencodings=utf8,gb2312,gb18030,ucs-bom,latin1
endif

function! MyBufClose()
    let currentBufNum = bufnr("%")
    let alternateBufNum = bufnr("#")

    if buflisted(alternateBufNum)
        buffer #
    else
        bnext
    endif

    if bufnr("%") == currentBufNum
        new
    endif

    if buflisted(currentBufNum)
        execute "bdelete! " . currentBufNum
    endif
endfunction

" 在buffer之间切换
nmap <silent> <leader>bn :bn<CR>
nmap <silent> <leader>bp :bp<CR>
nmap <silent> <leader>bc :call MyBufClose()<CR>

" 在Window之间切换
nmap <silent> <leader>wc :wincmd c<CR>
nmap <silent> <leader>wx :wincmd x<CR>
nmap <silent> <leader>wn :wincmd w<CR>
nmap <silent> <leader>wp :wincmd W<CR>
nmap <silent> <leader>wo :wincmd o<CR>

" 根据给定方向搜索当前光标下的单词，结合下面两个绑定使用
function! MyVisualSearch(direction) range
    let saved_reg = @"
    execute "normal! vgvy"
    let pattern = escape(@", '\\/.*$^~[]')
    let pattern = substitute(pattern, "\n$", "", "")
    if a:direction == 'b'
        execute "normal ?" . pattern . "<CR>"
    else
        execute "normal /" . pattern . "<CR>"
    endif
    let @/ = pattern
    let @" = saved_reg
endfunction

" 用 */# 向 前/后 搜索光标下的单词
vnoremap <silent> * :call MyVisualSearch('f')<CR>
vnoremap <silent> # :call MyVisualSearch('b')<CR>

" 常用绑定
inoremap <leader>1 ()<ESC>i
inoremap <leader>2 []<ESC>i
inoremap <leader>3 {}<ESC>i
inoremap <leader>4 <><ESC>i
inoremap <leader>5 {<ESC>o}<ESC>O
inoremap <leader>q ""<ESC>i
inoremap <leader>' ''<ESC>i
inoremap <silent> <C-L> <C-X><C-L>

" 常用缩写
iabbrev idate <C-R>=strftime("%Y-%m-%d")<CR>
iabbrev itime <C-R>=strftime("%H:%M")<CR>
iabbrev imail progliker@gmail.com
iabbrev iname Zhang Kang
iabbrev #i #include
iabbrev #d #define
iabbrev #e #endif


" plugin窗口的宽度，如TagList, NERD_tree等
let s:PlugWinSize = 30

" 配置TagList
" http://www.vim.org/scripts/script.php?script_id=273
nmap <silent> <leader>tt :TlistToggle<cr>
let Tlist_Show_One_File = 0
let Tlist_Exit_OnlyWindow = 1 
let Tlist_Use_Right_Window = 1
let Tlist_File_Fold_Auto_Close = 1
let Tlist_GainFocus_On_ToggleOpen = 0
let Tlist_WinWidth = s:PlugWinSize
let Tlist_Auto_Open = 0
let Tlist_Display_Prototype = 1

" 配置 OmniCppComplete.vim
" http://www.vim.org/scripts/script.php?script_id=1520
set completeopt=menu
let OmniCpp_ShowPrototypeInAbbr = 1 
let OmniCpp_DefaultNamespaces = ["std"]     " 逗号分割的字符串
let OmniCpp_MayCompleteScope = 1 
let OmniCpp_ShowPrototypeInAbbr = 1
let OmniCpp_SelectFirstItem = 2 

" 配置 NERD_commenter.vim
" http://www.vim.org/scripts/script.php?script_id=1218
" Toggle单行注释/“性感”注释/注释到行尾/取消注释
let NERDSpaceDelims = 1
map <leader>cc ,c<space>
map <leader>cs ,cs
map <leader>c$ ,c$
map <leader>cu ,cu

" 配置 NERD tree
" http://www.vim.org/scripts/script.php?script_id=1658
let NERDTreeShowHidden = 1
let NERDTreeWinPos = "right"
let NERDTreeWinSize = s:PlugWinSize 
nmap <leader>ll :NERDTreeToggle<cr>

function! MyBuildCppTags()
    let dir = getcwd()	" current directory

    if filereadable("tags")
        if (g:isWin) 
            let flag = delete(dir . "\\" . "tags")
        else
            let flag = delete("./" . "tags")
        endif
        if (flag != 0) 
            echoerr "Failed to build tags -- can't delete the tags"
            return
        endif
    endif

    if has("cscope") 
        " kill all cscope connection
        silent! execute "cs kill -1"
    endif

    " delete cscope.files
    if filereadable("cscope.files")
        if (g:isWin)
            let flag = delete(dir . "\\" . "cscope.files")
        else
            let flag = delete("./" . "cscope.files")
        endif
        if (flag != 0)
            echoerr "Failed to build tags -- can't delete the cscope.files"
            return
        endif
    endif

    " delete cscope.out
    if filereadable("cscope.out")
        if (g:isWin)
            let flag = delete(dir . "\\" . "cscope.out")
        else
            let flag = delete("./" . "cscope.out")
        endif
        if (flag != 0)
            echoerr "Failed to build tags -- can't delete the cscope.out"
            return
        endif
    endif

    let g:TEST = "WHY 2"
    if executable("ctags")
        silent! execute "!ctags -R --c++-kinds=+p --fields=+iaS --extra=+q ."
        let g:TEST = "WHY 3"
    endif

    if has("cscope") && executable("cscope")
        if (g:isWin)
            silent! execute "!dir /s/b *.c,*.cpp,*.h,*.cc,*.hpp >> cscope.files"
        else
            silent! execute "!find . -name '*.h' -o -name '*.c' -o -name '*.cpp' -o -name '*.cc' -o -name '*.hpp' > cscope.files"
        endif

        " build cscope.out
        silent! execute "!cscope -b"
        if filereadable("cscope.out")
            execute "cs add cscope.out"
        endif
    endif
endfunction

nmap <C-F12> :call MyBuildCppTags()<CR>

" 配置 cscope
if has("cscope")
    set csto=1
    set cst
    set nocsverb
    if filereadable("cscope.out")
        cs add cscope.out
    endif
    set csverb
    " s: C语言符号  g: 定义         d: 这个函数调用的函数 c: 调用这个函数的函数
    " t: 文本       e: egrep模式    f: 文件               i: include本文件的文件
    nmap <leader>ss :cs find s <C-R>=expand("<cword>")<CR><CR>:copen<CR>
    nmap <leader>sg :cs find g <C-R>=expand("<cword>")<CR><CR>
    nmap <leader>sc :cs find c <C-R>=expand("<cword>")<CR><CR>:copen<CR>
    nmap <leader>st :cs find t <C-R>=expand("<cword>")<CR><CR>:copen<CR>
    nmap <leader>se :cs find e <C-R>=expand("<cword>")<CR><CR>:copen<CR>
    nmap <leader>sf :cs find f <C-R>=expand("<cfile>")<CR><CR>:copen<CR>
    nmap <leader>si :cs find i ^<C-R>=expand("<cfile>")<CR>$<CR>:copen<CR>
    nmap <leader>sd :cs find d <C-R>=expand("<cword>")<CR><CR>:copen<CR>
endif

" 配置 BufExplorer
" http://vim.sourceforge.net/scripts/script.php?script_id=42
let g:bufExplorerDetailedHelp=1      " Show detailed help.
let g:bufExplorerShowRelativePath=0  " Show absolute paths.
let g:bufExplorerShowUnlisted=1      " Show unlisted buffers.
let g:bufExplorerSortBy='mru'        " Sort by most recently used.
let g:bufExplorerSplitRight=0        " Split left.
let g:bufExplorerSplitBelow=1        " Split new window below current.
autocmd BufWinEnter \[Buf\ List\] setl nonumber
nmap <silent> <Leader>bb :BufExplorerHorizontalSplit<CR>
nmap <silent> <Leader>be :BufExplorer<CR>
nmap <silent> <leader>bs :BufExplorerHorizontalSplit<CR>
nmap <silent> <leader>bv :BufExplorerVerticalSplit<CR>

" 配置 LookupFile
" http://www.vim.org/scripts/script.php?script_id=1581
" 增加一行（line 295）: let pattern = '\c' . a:pattern
let g:LookupFile_MinPatLength = 0
let g:LookupFile_PreserveLastPattern = 0
let g:LookupFile_PreservePatternHistory = 0
let g:LookupFile_AlwaysAcceptFirst = 1
let g:LookupFile_AllowNewFiles = 0
if (g:isWin) 
    if filereadable("filenametags")
        let g:LookupFile_TagExpr = '"filenametags"'
    endif
else
    if filereadable("./filenametags")
        let g:LookupFile_TagExpr = '"./filenametags"'
    endif
endif
nmap <silent> <leader>ff :LookupFile<CR>

function! LookupFile_IgnoreCaseFunc(pattern)
    let _tags = &tags
    try
        let &tags = eval(g:LookupFile_TagExpr)
        let newpattern = '\c' . a:pattern
        let tags = taglist(newpattern)
    catch
        echoerr "Exception: " . v:exception
        return ""
    finally
        let &tags = _tags
    endtry

    " Show the matches for what is typed so far.
    let files = map(tags, 'v:val["filename"]')
    return files
endfunction

let g:LookupFile_LookupFunc = 'LookupFile_IgnoreCaseFunc'

" 配置 ConqueTerm
nmap <silent> <leader>tb :ConqueTermSplit bash<CR>
nmap <silent> <leader>tp :ConqueTermSplit python<CR>

" 配置 VimTerminal
nmap <silent> <leader>ts :VimTermOpen<CR>

" 配置 DoxygenToolkit
let g:DoxygenToolkit_authorName="progliker"
let g:DoxygenToolkit_licenseTag="GNU License"
let g:DoxygenToolkit_undocTag="DOXIGEN_SKIP_BLOCK"
let g:DoxygenToolkit_briefTag_pre = "@brief\t"
let g:DoxygenToolkit_paramTag_pre = "@param\t"
let g:DoxygenToolkit_returnTag = "@return\t"
let g:DoxygenToolkit_briefTag_funcName = "no"
let g:DoxygenToolkit_maxFunctionProtoLines = 30
nmap <silent> <leader>dg : Dox<cr>

" 配置 Alternate.vim
" 进行 .h/.cpp文件间的切换
nmap <leader>aa :A<CR>
nmap <leader>av :AV<CR>

" 自动缩进文件
command! -range=% MyIndent :<line1>,<line2> normal i<CR>
nmap <leader>in :MyIndent<CR>

" 自己的项目配置文件
if (g:isWin) 
    if filereadable("myvimrc")
        source myvimrc
    endif
else
    if filereadable("./.myvimrc")
        source .myvimrc
    endif
endif

